package com.mxpio.erp.equipment.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.mxpio.erp.common.enums.*;
import com.mxpio.erp.common.equipment.entity.*;
import com.mxpio.erp.common.equipment.service.*;
import com.mxpio.erp.common.inventory.entity.WarehouseOrder;
import com.mxpio.erp.common.inventory.entity.WarehouseOrderLine;
import com.mxpio.erp.common.technology.entity.Item;
import com.mxpio.erp.common.vo.OrderExcuteLineVo;
import com.mxpioframework.common.exception.MBootException;
import com.mxpioframework.common.util.SpringUtil;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.dbconsole.model.DataGridWrapper;
import com.mxpioframework.dbconsole.service.DbService;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.lin.Linq;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.jpa.query.Operator;
import com.mxpioframework.jpa.query.Order;
import com.mxpioframework.security.entity.Dept;
import com.mxpioframework.security.entity.User;
import com.mxpioframework.security.entity.UserDept;
import com.mxpioframework.security.util.SecurityUtils;
import com.mxpioframework.system.service.SnRuleService;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 保养任务Service业务层处理
 *
 * @author Cheng
 * @date 2023-07-28
 */
@Service
@Slf4j
public class EquipmentUpkeepTaskServiceImpl extends BaseServiceImpl<EquipmentUpkeepTask> implements EquipmentUpkeepTaskService {

    public static final String DEPART_RELEASE_TARGET = "department";
    public static final String PERSON_GROUP_RELEASE_TARGET = "person_group";
    public static final String PERSONAL_RELEASE_TARGET = "personal";
    public static final String ASSIGN_MODE = "assign";
    public static final String GRAB_MODE = "grab";

    @Resource
    private EquipmentAreaService equipmentAreaService;
    @Resource
    private EquipmentPersonGroupService personGroupService;
    @Resource
    private EquipmentUpkeepTaskDetailService upkeepTaskDetailService;
    @Resource
    private EquipmentUpkeepTaskOperationService upkeepTaskOperationService;
    @Resource
    private EquipmentUpkeepTaskTransferService upkeepTaskTransferService;

    @Resource
    private EquipmentUpkeepTaskAssistantsService equipmentUpkeepTaskAssistantsService;

    @Value("${pmis.create:}")
    private String create;

    /*@Autowired
    private RestTemplate restTemplate;*/

    @Autowired
    private DbService dbService;

    @Value("${pmis.dbInfoId:}")
    private String dbInfoId;


    @Override
    @Transactional(readOnly = true)
    public Page<EquipmentUpkeepTask> taskPage(String flag, Pageable page, Criteria criteria) {
        Linq linq = JpaUtil.linq(EquipmentUpkeepTask.class).where(criteria);
        String username = SecurityUtils.getLoginUsername();
        if("task".equals(flag)){
            linq = linq.or()
                    .equal("director", username)
                    .equal("executor", username)
                    .equal("dispatchUser", username)
                    .equal("createBy", username)
                    .end();
        }else if ("release".equals(flag)) {
            linq = linq
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.START.getCode())
                    .or()
                    .equal("director", username)
                    .equal("executor", username)
                    .equal("dispatchUser", username)
                    .equal("createBy", username)
                    .end();
        }else if ("send".equals(flag)) {
            linq = linq
                    //派工模式为派工
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.RELEASE.getCode())
                    .equal("dispatchMode", ASSIGN_MODE)
                    .equal("director", username);
        }else if (GRAB_MODE.equals(flag)) {
            List<Dept> depts = queryUserDeparts(username);
            List<String> departs = depts.stream().map(a -> a.getId()).collect(Collectors.toList());
            List<String> groups = personGroupService.selectByUsername(username);
            groups.addAll(departs);
            linq = linq
                    //派工模式为抢单
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.RELEASE.getCode())
                    .equal("dispatchMode", GRAB_MODE)
                    .in("releaseTargetId", groups);
        }else if ("execute".equals(flag)) {
            linq = linq
                    .equal("executor", username)
                    .or()
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.WAIT_EXECUT.getCode())
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.EXECUT.getCode())
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.PAUSE.getCode())
                    .end();
        }else if ("toExecute".equals(flag)) {
            linq = linq
                    .equal("executor", username)
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.WAIT_EXECUT.getCode());
        }else if ("executing".equals(flag)) {
            linq = linq
                    .equal("executor", username)
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.EXECUT.getCode());
        }else if ("stop".equals(flag)) {
            linq = linq
                    .equal("executor", username)
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.PAUSE.getCode());
        }else if ("record".equals(flag)) {
            linq = linq
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.ZIPPED.getCode())
                    .or()
                    .equal("director", username)
                    .equal("executor", username)
                    .equal("dispatchUser", username)
                    .equal("createBy", username)
                    .end();
        }else if ("executeOverdue".equals(flag)) {//逾期未执行
            //当前时间大于预计完成时间的未完工工单
            linq = linq
                    .equal("executor", username)
                    .or()
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.WAIT_EXECUT.getCode())
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.EXECUT.getCode())
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.PAUSE.getCode())
                    .end()
                    .gt("planEndTime", DateUtil.now());
        } else if ("overdueFinish".equals(flag)) {//逾期完成
            linq = linq
                    .equal("orderStatus", EquipmentEnums.UpkeepStatus.PAUSE.getCode())
                    .or()
                    .equal("director", username)
                    .equal("executor", username)
                    .equal("dispatchUser", username)
                    .equal("createBy", username)
                    .end()
                    .lt("planEndTime","actualEndTime");
        }

        return linq.paging(page);
    }

    @Override
    @Transactional(readOnly = true)
    public List<EquipmentUpkeepTask> queryExecutingList() {
        return JpaUtil.linq(EquipmentUpkeepTask.class).in("orderStatus", 30, 40, 45).list();
    }

    @Override
    @Transactional
    public void saveTask(EquipmentUpkeepTask upkeepTask) {
        upkeepTask.setOrderStatus(EquipmentEnums.UpkeepStatus.START.getCode());
        //重新计算计划下达时间
        if (upkeepTask.getIsAutoRelease()==Integer.parseInt(CommonEnums.YesNo.YES.getCode())){//自动释放
            upkeepTask.setPlanReleaseTime(DateUtils.addDays(upkeepTask.getPlanStartTime(),0-upkeepTask.getAdvanceTime()));
        }
        /*if (EquipmentEnums.UpkeepPlanTarget.AREA_TARGET.getCode().equals(upkeepTask.getTargetType())) {
            // 查询区域信息
            EquipmentArea area = JpaUtil.getOne(EquipmentArea.class,upkeepTask.getTargetId());
            if (area == null) {
                return;
            }
            upkeepTask.setTargetCode(area.getAreaCode());
            if (area.getPid() != null && !"0".equals(area.getPid())) {
                String parentAllName = equipmentAreaService.getParentAllNameByPid(area.getPid());
                upkeepTask.setTargetName(parentAllName + area.getAreaName());
            } else {
                upkeepTask.setTargetName(area.getAreaName());
            }
        }*/
        // 获取部门或群组的负责人
        /*if (DEPART_RELEASE_TARGET.equals(upkeepTask.getReleaseTargetType())) {
            String departmentDirector = getDepartmentDirector(upkeepTask.getReleaseTargetId(), upkeepTask.getDispatchMode());
            upkeepTask.setDirector(departmentDirector);
        } else if (PERSON_GROUP_RELEASE_TARGET.equals(upkeepTask.getReleaseTargetType())) {
            // 获取群组主管
            EquipmentPersonGroup tpmPersonGroup = JpaUtil.getOne(EquipmentPersonGroup.class,upkeepTask.getReleaseTargetId());
            if (StringUtils.isEmpty(tpmPersonGroup.getDirectorId()) && ASSIGN_MODE.equals(upkeepTask.getDispatchMode())) {
                throw new MBootException("派工模式下该下达目标无负责人");
            }
            upkeepTask.setDirector(tpmPersonGroup.getDirectorId());
        }*/
        save(upkeepTask);
    }

    @Override
    @Transactional
    public void updateTask(EquipmentUpkeepTask upkeepTask) {

        EquipmentUpkeepTask byId = this.getById(EquipmentUpkeepTask.class, upkeepTask.getBizNo());
        if (!byId.getOrderStatus().equals(EquipmentEnums.UpkeepStatus.START.getCode()) && !byId.getOrderStatus().equals(EquipmentEnums.UpkeepStatus.RELEASE.getCode())){
            throw new MBootException("非待下达和待派工不可编辑123456789");
        }

        //重新计算计划下达时间
        if (upkeepTask.getIsAutoRelease()==Integer.parseInt(CommonEnums.YesNo.YES.getCode())){//自动释放
            upkeepTask.setPlanReleaseTime(DateUtils.addDays(upkeepTask.getPlanStartTime(),0-upkeepTask.getAdvanceTime()));
            byId.setPlanReleaseTime(upkeepTask.getPlanReleaseTime());
        }

        /*if (EquipmentEnums.UpkeepPlanTarget.AREA_TARGET.getCode().equals(upkeepTask.getTargetType())) {
            // 查询区域信息
            EquipmentArea area = JpaUtil.getOne(EquipmentArea.class,upkeepTask.getTargetId());
            if (area == null) {
                return;
            }
            upkeepTask.setTargetCode(area.getAreaCode());
            if (area.getPid() != null && !"0".equals(area.getPid())) {
                String parentAllName = equipmentAreaService.getParentAllNameByPid(area.getPid());
                upkeepTask.setTargetName(parentAllName +"/"+ area.getAreaName());
            } else {
                upkeepTask.setTargetName(area.getAreaName());
            }
        }
        // 获取部门或群组的负责人
        if (DEPART_RELEASE_TARGET.equals(upkeepTask.getReleaseTargetType())) {
            String departmentDirector = getDepartmentDirector(upkeepTask.getReleaseTargetId(), upkeepTask.getDispatchMode());
            upkeepTask.setDirector(departmentDirector);
        } else if (PERSON_GROUP_RELEASE_TARGET.equals(upkeepTask.getReleaseTargetType())) {
            // 获取群组主管
            EquipmentPersonGroup tpmPersonGroup = JpaUtil.getOne(EquipmentPersonGroup.class,upkeepTask.getReleaseTargetId());
            if (StringUtils.isEmpty(tpmPersonGroup.getDirectorId()) && ASSIGN_MODE.equals(upkeepTask.getDispatchMode())) {
                throw new MBootException("派工模式下该下达目标无负责人");
            }
            upkeepTask.setDirector(tpmPersonGroup.getDirectorId());
        }*/
        byId.setAdvanceTime(upkeepTask.getAdvanceTime());
        byId.setTargetId(upkeepTask.getTargetId());
        byId.setUpkeepPersonGroupCode(upkeepTask.getUpkeepPersonGroupCode());
        byId.setEngineerPersonGroupCode(upkeepTask.getEngineerPersonGroupCode());
        byId.setUpkeepType(upkeepTask.getUpkeepType());
        byId.setPlanStartTime(upkeepTask.getPlanStartTime());
        byId.setPlanHourRation(upkeepTask.getPlanHourRation());
        byId.setPlanEndTime(upkeepTask.getPlanEndTime());
        byId.setIsAutoRelease(upkeepTask.getIsAutoRelease());
        byId.setIsPush(upkeepTask.getIsPush());
        this.update(byId);
    }

    @Override
    @Transactional
    public void release(String id) {
        EquipmentUpkeepTask upkeepTask = this.getById(EquipmentUpkeepTask.class,id);
        if (upkeepTask == null) {
            throw new MBootException("未找到对应数据");
        }
        if (!EquipmentEnums.UpkeepStatus.START.getCode().equals(upkeepTask.getOrderStatus())) {
            throw new MBootException("工单状态不正确，不允许执行");
        }
        upkeepTask.setOrderStatus(EquipmentEnums.UpkeepStatus.RELEASE.getCode());
        upkeepTask.setReleaseTime(new Date());
        //处理计划生成任务的下一任务标识字段
        if (StringUtils.isNotBlank(upkeepTask.getPlanId())){//
            JpaUtil.linu(EquipmentUpkeepTask.class)
                    .equal("planId", upkeepTask.getPlanId())
                    .equal("nextFlag", CommonEnums.YesNo.YES.getCode())
                    .set("nextFlag",CommonEnums.YesNo.NO.getCode())
                    .update();//更新nextFlag标识字段
            upkeepTask.setNextFlag(CommonEnums.YesNo.NO.getCode());
            Integer taskIndex = upkeepTask.getTaskIndex();
            Criteria orderCri = Criteria.create();
            orderCri.addOrder(new Order("taskIndex",false));
            //查找下一个任务
            List<EquipmentUpkeepTask> nextList = JpaUtil.linq(EquipmentUpkeepTask.class)
                    .equal("planId", upkeepTask.getPlanId())
                    .gt("taskIndex", taskIndex)
                    //.equal("nextFlag", CommonEnums.YesNo.NO.getCode())
                    .where(orderCri)
                    .list();
            if(!nextList.isEmpty()){
                EquipmentUpkeepTask next = nextList.get(0);
                next.setNextFlag(CommonEnums.YesNo.YES.getCode());
                JpaUtil.update(next);
            }
        }

        if (PERSONAL_RELEASE_TARGET.equals(upkeepTask.getReleaseTargetType())) {
            // 如果是下达目标是个人，则直接跳过派工状态
            upkeepTask.setOrderStatus(EquipmentEnums.UpkeepStatus.WAIT_EXECUT.getCode());
            upkeepTask.setDispatchTime(new Date());
            upkeepTask.setExecutor(upkeepTask.getReleaseTargetId());
        }
        this.update(upkeepTask);
    }

    @Override
    @Transactional
    public void dispatch(String id, String executor) throws MBootException {
        EquipmentUpkeepTask upkeepTask = this.getById(EquipmentUpkeepTask.class,id);
        if (upkeepTask == null) {
            throw new MBootException("未找到对应数据");
        }
        // 判断工单状态
        if (!EquipmentEnums.UpkeepStatus.RELEASE.getCode().equals(upkeepTask.getOrderStatus())) {
            throw new MBootException("工单状态不正确，不允许执行");
        }
        // 判断派工模式
        /*if (GRAB_MODE.equals(upkeepTask.getDispatchMode())) {
            throw new MBootException("非派工模式");
        }*/
        upkeepTask.setDispatchMode(ASSIGN_MODE);
        String loginUsername = SecurityUtils.getLoginUsername();
        upkeepTask.setExecutor(executor);
        upkeepTask.setDispatchTime(new Date());
        upkeepTask.setDispatchUser(loginUsername);
        upkeepTask.setOrderStatus(EquipmentEnums.UpkeepStatus.WAIT_EXECUT.getCode());

        this.update(upkeepTask);
    }

    @Override
    @Transactional
    public void grab(String id) throws MBootException {
        EquipmentUpkeepTask upkeepTask = this.getById(EquipmentUpkeepTask.class,id);
        if (upkeepTask == null) {
            throw new MBootException("工单不存在");
        }
        // 判断工单状态
        if (!EquipmentEnums.UpkeepStatus.RELEASE.getCode().equals(upkeepTask.getOrderStatus())) {
            throw new MBootException("工单状态不正确");
        }
        // 判断派工模式
        /*if (ASSIGN_MODE.equals(upkeepTask.getDispatchMode())) {
            throw new MBootException("非抢单模式");
        }*/
        upkeepTask.setDispatchMode(GRAB_MODE);
        String loginUsername = SecurityUtils.getLoginUsername();
        upkeepTask.setExecutor(loginUsername);
        upkeepTask.setDispatchTime(new Date());
        upkeepTask.setDispatchUser(loginUsername);
        upkeepTask.setOrderStatus(EquipmentEnums.UpkeepStatus.WAIT_EXECUT.getCode());

        this.update(upkeepTask);
    }

    @Override
    @Transactional
    public void excut(EquipmentUpkeepTask equipmentUpkeepTask) throws MBootException {
        EquipmentUpkeepTask tpmUpkeepTaskEntity = this.getById(EquipmentUpkeepTask.class, equipmentUpkeepTask.getBizNo());
        if (tpmUpkeepTaskEntity == null) {
            throw new MBootException("未找到对应数据");
        }

        if (!EquipmentEnums.UpkeepStatus.EXECUT.getCode().equals(tpmUpkeepTaskEntity.getOrderStatus())) {
            throw new MBootException("工单状态不正确，不允许执行");
        }

        Date date = new Date();
        tpmUpkeepTaskEntity.setActualEndTime(date);

//        //判断是否逾期
//        if (date.getTime() > tpmUpkeepTaskEntity.getPlanEndTime().getTime()) {
//            tpmUpkeepTaskEntity.setOverFlag(1);
//        }
        LocalDate currentDate = LocalDate.now(); //获取当前时间
        Date planEndTime = tpmUpkeepTaskEntity.getPlanEndTime();
        LocalDate planEndLocalDate = planEndTime.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDate();
        if (currentDate.isAfter(planEndLocalDate)){
            tpmUpkeepTaskEntity.setOverFlag(1);//当计划时间超过当前时间时，判断为当前项目逾期
        }else{
            tpmUpkeepTaskEntity.setOverFlag(0);
        }
        tpmUpkeepTaskEntity.setOrderStatus(EquipmentEnums.UpkeepStatus.REPORT.getCode());//待汇报

        // 计算维修工时
        Criteria taskOperationC = Criteria.create();
        taskOperationC.addCriterion("bizNo", Operator.EQ,tpmUpkeepTaskEntity.getBizNo());
        taskOperationC.addOrder(new Order("createTime",false));//按创建时间升序
        List<EquipmentUpkeepTaskOperation> tpmUpkeepTaskOperations = JpaUtil.linq(EquipmentUpkeepTaskOperation.class).where(taskOperationC).list();
        if (!CollectionUtils.isEmpty(tpmUpkeepTaskOperations)) {
            Date beginStop = new Date();
            long totalWorkTime = DateUtil.between(tpmUpkeepTaskEntity.getActualStartTime(), date, DateUnit.MINUTE);
            long totalStopTime = 0;
            // 循环计算暂停时长
            for (int i = 0; i < tpmUpkeepTaskOperations.size(); i++) {
                if ("保养暂停".equals(tpmUpkeepTaskOperations.get(i).getOperate())) {
                    beginStop = tpmUpkeepTaskOperations.get(i).getOperateTime();
                }
                if ("保养暂停结束".equals(tpmUpkeepTaskOperations.get(i).getOperate())) {
                    totalStopTime += DateUtil.between(beginStop,tpmUpkeepTaskOperations.get(i).getOperateTime(), DateUnit.MINUTE);
                }
            }
            tpmUpkeepTaskEntity.setWorkMinutes(totalWorkTime - totalStopTime);
        }

        insertOperate(tpmUpkeepTaskEntity.getBizNo(), "保养完成", "保养完成");
        // 发起签核
        this.update(tpmUpkeepTaskEntity);
    }

    @Override
    @Transactional
    public void startExcut(String id) throws MBootException {
        EquipmentUpkeepTask upkeepTask = this.getById(EquipmentUpkeepTask.class, id);
        if (upkeepTask == null) {
            throw new MBootException("未找到对应数据");
        }
        // 判断工单状态
        if (!EquipmentEnums.UpkeepStatus.WAIT_EXECUT.getCode().equals(upkeepTask.getOrderStatus())) {
            throw new MBootException("工单非待开始状态");
        }
        upkeepTask.setExecStatus(EquipmentEnums.UpkeepTaskExecStatus.EXEC.getCode());//执行状态
        upkeepTask.setActualStartTime(new Date());
        upkeepTask.setOrderStatus(EquipmentEnums.UpkeepStatus.EXECUT.getCode());
        this.update(upkeepTask);
        insertOperate(upkeepTask.getBizNo(), "开始保养", "开始执行");
    }

    @Override
    @Transactional
    public void stopUpkeepById(String reason, String id) {
        EquipmentUpkeepTask upkeepTask = this.getById(EquipmentUpkeepTask.class, id);
        if (upkeepTask == null || !EquipmentEnums.UpkeepStatus.EXECUT.getCode().equals(upkeepTask.getOrderStatus())) {
            new MBootException("实体未找到或未开始保养状态！");
        }
        upkeepTask.setOrderStatus(EquipmentEnums.UpkeepStatus.PAUSE.getCode());
        this.update(upkeepTask);

        //设置操作记录
        insertOperate(id, "保养暂停", reason);
    }

    @Override
    @Transactional
    public void endStop(String id) {
        EquipmentUpkeepTask upkeepTask = this.getById(EquipmentUpkeepTask.class, id);
        if (upkeepTask == null || !EquipmentEnums.UpkeepStatus.PAUSE.getCode().equals(upkeepTask.getOrderStatus())) {
            new MBootException("实体未找到或非暂停状态！");
        }
        upkeepTask.setOrderStatus(EquipmentEnums.UpkeepStatus.EXECUT.getCode());
        this.update(upkeepTask);

        //设置操作记录
        insertOperate(id, "保养暂停结束", "保养暂停结束");
    }

    @Override
    @Transactional
    public void reSend(String id, String executor, String reason) throws MBootException {
        EquipmentUpkeepTask upkeepTask = this.getById(EquipmentUpkeepTask.class, id);
        if (upkeepTask == null) {
            throw new MBootException("未找到对应数据");
        }
        // 判断工单状态
        if (Integer.parseInt(upkeepTask.getOrderStatus()) >= Integer.valueOf(EquipmentEnums.UpkeepStatus.EVA.getCode())) {
            throw new MBootException("工单状态不正确，不允许执行");
        }

        EquipmentUpkeepTaskTransfer tpmUpkeepTaskTransfer = new EquipmentUpkeepTaskTransfer();
        tpmUpkeepTaskTransfer.setBizNo(id);
        tpmUpkeepTaskTransfer.setOldExecutor(upkeepTask.getExecutor());
        tpmUpkeepTaskTransfer.setNewExecutor(executor);
        tpmUpkeepTaskTransfer.setReason(reason);
        tpmUpkeepTaskTransfer.setTransferTime(new Date());
        upkeepTaskTransferService.save(tpmUpkeepTaskTransfer);

        upkeepTask.setExecutor(executor);
        this.update(upkeepTask);
    }

    @Override
    @Transactional
    public void signOffBack(String id, String reason) {
        EquipmentUpkeepTask upkeepTask = this.getById(EquipmentUpkeepTask.class, id);
        if (upkeepTask == null) {
            throw new MBootException("id或者实体不存在！");
        }
        // 判断工单状态
        if ( !EquipmentEnums.UpkeepStatus.ZIPPED.getCode().equals(upkeepTask.getOrderStatus())) {
            throw new MBootException("保养工单状态非结束状态！");
        }

        upkeepTask.setOrderStatus(EquipmentEnums.UpkeepStatus.WAIT_EXECUT.getCode());
        this.update(upkeepTask);
    }

    /**
     * 添加操作记录
     *
     * @param repairId 任务ID
     * @param operate  操作
     * @param reason   原因（主要用具回退填写原因）
     */
    private void insertOperate(String repairId, String operate, String reason) {
        insertOperate(repairId, operate, reason, 0);
    }


    /**
     * 添加操作记录
     *
     * @param repairId 任务ID
     * @param operate  操作
     * @param reason   原因（主要用具回退填写原因）
     */
    private void insertOperate(String repairId, String operate, String reason, long time) {
        EquipmentUpkeepTaskOperation operation = new EquipmentUpkeepTaskOperation();
        //设置任务ID
        operation.setBizNo(repairId);
        //设置操作名称
        operation.setOperate(operate);
        //设置操作原因
        operation.setReason(reason);
        //设置操作时间
        if (time > 0 ){
            operation.setOperateTime(new Date(time));
        }else{
            operation.setOperateTime(new Date());
        }
        //获取当前登录用户
        User loginUser = SecurityUtils.getLoginUser();
        //设置操作人
        operation.setOperator(loginUser.getNickname() + "/" + loginUser.getUsername());
        //保存
        upkeepTaskOperationService.save(operation);
    }

    private String getDepartmentDirector(String departmentId, String dispatchMode) throws MBootException {
        List<User> users = JpaUtil
                .linq(User.class)
                .exists(UserDept.class)
                .equalProperty("userId", "username")
                .equal("deptId", departmentId)
                .end()
                .list();
        if (CollectionUtils.isEmpty(users) && ASSIGN_MODE.equals(dispatchMode)) {
            throw new MBootException("派工模式下该下达目标无负责人");
        } else {
            return users.get(0).getUsername();
        }
    }

    private List<Dept> queryUserDeparts(String username){
        return JpaUtil.linq(Dept.class)
                .exists(UserDept.class)
                .equalProperty("deptId","id")
                .equal("userId",username)
                .list();
    }

    @Override
    @Transactional
    public Result<?> change(EquipmentUpkeepTask task) {
        EquipmentUpkeepTask bean = this.getById(EquipmentUpkeepTask.class, task.getBizNo());
        if (bean == null || bean.getOrderStatus() != EquipmentEnums.UpkeepStatus.EXECUT.getCode()) {
            return Result.error("实体未找到或未开始保养状态！");
        }
        if (bean.getOrderStatus().equals(EquipmentEnums.UpkeepStatus.VETO.getCode())){
            return Result.error("单据已否决，不允许此操作！");
        }
        String changestatus = task.getExecStatus();
        String execStatusStr = "";
        bean.setExecStatus(changestatus);
        if (StringUtils.equals(changestatus,EquipmentEnums.UpkeepTaskExecStatus.OUTSOURCE.getCode())){//委外情况
            bean.setExecutor(task.getExecutor());//更换责任人为委外人
            execStatusStr = "委外";
        }else if (StringUtils.equals(changestatus,EquipmentEnums.UpkeepTaskExecStatus.WAIT.getCode())){//等件
            execStatusStr = "等件";
            if (!bean.getOrderStatus().equals(EquipmentEnums.UpkeepStatus.PAUSE.getCode())){//暂停
                bean.setOrderStatus(EquipmentEnums.UpkeepStatus.PAUSE.getCode());//单据暂停
                insertOperate(bean.getBizNo(), "保养暂停", execStatusStr+"；由单据变更操作触发。");
            }

        }else if (StringUtils.equals(changestatus,EquipmentEnums.UpkeepTaskExecStatus.PAUSE.getCode())){//搁置
            execStatusStr = "搁置";
            if (!bean.getOrderStatus().equals(EquipmentEnums.UpkeepStatus.PAUSE.getCode())){//暂停
                bean.setOrderStatus(EquipmentEnums.UpkeepStatus.PAUSE.getCode());//单据暂停
                insertOperate(bean.getBizNo(), "保养暂停", execStatusStr+"；由单据变更操作触发。");
            }
        }else if (StringUtils.equals(changestatus,EquipmentEnums.UpkeepTaskExecStatus.EXEC.getCode())){//委外情况
            execStatusStr = "执行";
            if (bean.getOrderStatus().equals(EquipmentEnums.UpkeepStatus.PAUSE.getCode())){//暂停
                bean.setOrderStatus(EquipmentEnums.UpkeepStatus.EXECUT.getCode());//单据恢复
                insertOperate(bean.getBizNo(), "保养暂停结束", "保养暂停结束；"+task.getVetoReason()+"；由单据变更操作触发。");
            }
        }
        this.update(bean);
        //设置操作记录
        insertOperate(bean.getBizNo(), "保养变更-"+execStatusStr, task.getVetoReason());//与前端共识，此处用vetoReason传递变更原因字段
        return Result.OK();
    }

    @Override
    @Transactional
    public Result<?> veto(EquipmentUpkeepTask task) {
        EquipmentUpkeepTask bean = this.getById(EquipmentUpkeepTask.class, task.getBizNo());
        if (bean == null ) {
            return Result.error("未找到实体对象");
        }
        if (!bean.getOrderStatus().equals(EquipmentEnums.UpkeepStatus.WAIT_EXECUT.getCode())){
            return Result.error("仅待执行状态可以否决！");
        }
        bean.setOrderStatus(EquipmentEnums.UpkeepStatus.VETO.getCode());
        bean.setVetoReason(task.getVetoReason());
        this.update(bean);

        insertOperate(bean.getBizNo(), "否决", task.getVetoReason());
        return Result.OK(bean);
    }

    @Override
    @Transactional
    public Result<?> submit(EquipmentUpkeepTask tempTask) {
        EquipmentUpkeepTask tpmUpkeepTaskEntity = this.getById(EquipmentUpkeepTask.class, tempTask.getBizNo());
        if (tpmUpkeepTaskEntity == null) {
            return Result.error("实体未找到！");
        }
        if (!(StringUtils.equals(tpmUpkeepTaskEntity.getOrderStatus() , EquipmentEnums.UpkeepStatus.EXECUT.getCode())
                ||StringUtils.equals(tpmUpkeepTaskEntity.getOrderStatus() , EquipmentEnums.UpkeepStatus.REPORT.getCode()))) {
            return Result.error("仅执行中和待汇报状态允许提交操作！");
        }
        if (tpmUpkeepTaskEntity.getOrderStatus().equals(EquipmentEnums.UpkeepStatus.VETO.getCode())){
            return Result.error("单据已否决，不允许此操作！");
        }

        tpmUpkeepTaskEntity.setActualHourRation(tempTask.getActualHourRation());//汇报工时
        tpmUpkeepTaskEntity.setEqpStatus(tempTask.getEqpStatus());
        tpmUpkeepTaskEntity.setAttachFile(tempTask.getAttachFile());
        if (tpmUpkeepTaskEntity.getOrderStatus().equals(EquipmentEnums.UpkeepStatus.EXECUT.getCode())){//如果是由执行中状态跳过完成操作直接提交的情况，需要处理
            Date date = new Date();
            tpmUpkeepTaskEntity.setActualEndTime(date);
            //判断是否逾期
//            if (date.getTime() > tpmUpkeepTaskEntity.getPlanEndTime().getTime()) {
//                tpmUpkeepTaskEntity.setOverFlag(1);
//            }
            LocalDate currentDate = LocalDate.now(); //获取当前时间
            Date planEndTime = tpmUpkeepTaskEntity.getPlanEndTime();
            LocalDate planEndLocalDate = planEndTime.toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDate();
            if (currentDate.isAfter(planEndLocalDate)){
                tpmUpkeepTaskEntity.setOverFlag(1);//当计划时间超过当前时间时，判断为当前项目逾期
            }else{
                tpmUpkeepTaskEntity.setOverFlag(0);
            }
            // 计算维修工时
            List<EquipmentUpkeepTaskOperation> tpmUpkeepTaskOperations = JpaUtil.linq(EquipmentUpkeepTaskOperation.class).equal("bizNo", tpmUpkeepTaskEntity.getBizNo()).list();
            if (!CollectionUtils.isEmpty(tpmUpkeepTaskOperations)) {
                Date beginStop = new Date();
                long totalWorkTime = DateUtil.between(tpmUpkeepTaskEntity.getActualStartTime(), date, DateUnit.MINUTE);
                long totalStopTime = 0;
                // 循环计算暂停时长
                for (int i = 0; i < tpmUpkeepTaskOperations.size(); i++) {
                    if ("保养暂停".equals(tpmUpkeepTaskOperations.get(i).getOperate())) {
                        beginStop = tpmUpkeepTaskOperations.get(i).getOperateTime();
                    }
                    if ("保养暂停结束".equals(tpmUpkeepTaskOperations.get(i).getOperate())) {
                        totalStopTime += DateUtil.between(beginStop,tpmUpkeepTaskOperations.get(i).getOperateTime(), DateUnit.MINUTE);
                    }
                }
                tpmUpkeepTaskEntity.setWorkMinutes(totalWorkTime - totalStopTime);
            }
        }
        for (EquipmentUpkeepTaskDetail tpmUpkeepTaskDetail : tempTask.getUpkeepTaskDetails()) {
            if (tpmUpkeepTaskDetail.getIsRecord() == 0) {
                tpmUpkeepTaskDetail.setActualVaule("无需记录");
            }
            upkeepTaskDetailService.update(tpmUpkeepTaskDetail);
        }
        // 查询是否有未记录的明细
        Long count = JpaUtil.linq(EquipmentUpkeepTaskDetail.class)
                .equal("bizNo", tempTask.getBizNo())
                .equal("isRecord", 1)
                .isNull("actualVaule")
                .count();
        if (count > 0) {
            return Result.error("存在未填写的保养任务明细，不能提交");
        }

        tpmUpkeepTaskEntity.setOrderStatus(EquipmentEnums.UpkeepStatus.CHECK.getCode());//待验收
        this.update(tpmUpkeepTaskEntity);
        //更新设备台账上次保养日期字段：
        EquipmentEqpBasics basics = JpaUtil.getOne(EquipmentEqpBasics.class, tpmUpkeepTaskEntity.getTargetId());
        if (basics!=null){
            basics.setLastUpkeepDate(new Date());
            JpaUtil.update(basics);
        }
        insertOperate(tpmUpkeepTaskEntity.getBizNo(), "保养提交", "保养提交");
        return Result.OK(tpmUpkeepTaskEntity);
    }

    @Override
    @Transactional
    public Result<?> check(EquipmentUpkeepTask task) {
        EquipmentUpkeepTask bean = this.getById(EquipmentUpkeepTask.class,task.getBizNo());
        if (bean == null ) {
            return Result.error("实体未找到！");
        }
        if (!bean.getOrderStatus().equals(EquipmentEnums.UpkeepStatus.CHECK.getCode())) {
            return Result.error("必须是待验收状态单据允许验收操作！");
        }
        if (bean.getOrderStatus().equals(EquipmentEnums.UpkeepStatus.VETO.getCode())){
            return Result.error("单据已否决，不允许此操作！");
        }
        Integer isUsable = task.getIsUsable();
        String checkResult = "";
        if (isUsable.equals(1)){
            checkResult = "是/"+task.getCheckResult();
        }else{
            checkResult = "否/"+task.getCheckResult();
        }

        bean.setOrderStatus(EquipmentEnums.UpkeepStatus.EVA.getCode());
        bean.setAcceptor(SecurityUtils.getLoginUsername());//记录验收人
        this.update(bean);
        //设置操作记录
        insertOperate(bean.getBizNo(), "保养验收", checkResult);
        return Result.OK();
    }

    @Override
    @Transactional
    public Result<?> evaluate(List<EquipmentUpkeepTaskEvaluate> evaluates) {
        if (evaluates==null||evaluates.isEmpty()){
            return Result.error("评价内容为空！");
        }
        JpaUtil.save(evaluates);
        EquipmentUpkeepTask task = this.getById(EquipmentUpkeepTask.class,evaluates.get(0).getBizNo());
        if (task == null ) {
            return Result.error("未找到维修任务实体对象");
        }
        if (!task.getOrderStatus().equals(EquipmentEnums.UpkeepStatus.EVA.getCode()) ){
            return Result.error("仅待评价状态可以评价！");
        }
        task.setOrderStatus(EquipmentEnums.UpkeepStatus.ZIPING.getCode());
        task.setEvaluateDate(new Date());
        task.setEvaluateUser(SecurityUtils.getLoginUser().getUsername());
        this.update(task);

        //设置操作记录
        insertOperate(task.getBizNo(), "评分", "评分");
        return Result.OK(evaluates);
    }

    @Override
    @Transactional
    public Result<List<EquipmentUpkeepTaskPickupLine>> executePickUp(EquipmentUpkeepTask order, List<OrderExcuteLineVo> lines) {
        if (lines==null||lines.isEmpty()){
            return Result.error("提交数据为空");
        }
        SnRuleService snRuleService = SpringUtil.getBean(SnRuleService.class);
        String expression = order.getBizNo()+"@"+"###";
        Set<String> itemCodeSet = lines.stream().map(OrderExcuteLineVo::getItemCode).collect(Collectors.toSet());
        List<Item> dbItemList = JpaUtil.linq(Item.class).in("itemCode", itemCodeSet).list();
        Map<String,Item> dbItemMap = JpaUtil.index(dbItemList, "itemCode");
        //生成维修单明细（领料明细）
        List<EquipmentUpkeepTaskPickupLine> pickupLineList = new ArrayList<>();
        for (OrderExcuteLineVo vo:lines){
            String lineNoStr = (String) snRuleService.execute(expression, null);
            String[] split = lineNoStr.split("@");
            EquipmentUpkeepTaskPickupLine line = new EquipmentUpkeepTaskPickupLine();
            line.setBizNo(order.getBizNo());
            line.setLineNo(split[1]);
            Item item = dbItemMap.get(vo.getItemCode());
            if (item==null){
                throw new MBootException("提交的领料记录中【"+vo.getItemCode()+"】在系统中不存在！！！");
            }
            //关联物料信息
            line.setItemCode(item.getItemCode());
            line.setItemGroupCode(item.getItemGroupCode());
            line.setDrawingNo(item.getDrawingNo());
            line.setItemName(item.getItemName());
            line.setItemSpec(item.getItemSpec());
            line.setUnitCode(item.getUnitCode());

            line.setWhCode(vo.getWhCode());
            line.setQuantity(vo.getQuantity());
            pickupLineList.add(line);
        }
        JpaUtil.save(pickupLineList);
        List<OrderExcuteLineVo> orderExcuteVos = new ArrayList<>();
        for(EquipmentUpkeepTaskPickupLine line:pickupLineList){
            OrderExcuteLineVo vo = new OrderExcuteLineVo();
            vo.setBizOrderNo(order.getBizNo());
            vo.setBizOrderlineNo(line.getLineNo());
            vo.setItemCode(line.getItemCode());
            vo.setQuantity(line.getQuantity());
            vo.setWhCode(line.getWhCode());
            orderExcuteVos.add(vo);
        }
        //生成对应通知单
        Map<String, UpkeepPickupNotice> noticeMap = new HashMap<>();
        Map<String,List<OrderExcuteLineVo>> voMap = new HashMap<>();
        for(OrderExcuteLineVo orderExcuteVo : orderExcuteVos) {
            UpkeepPickupNotice notice = noticeMap.get(orderExcuteVo.getWhCode());
            if(notice == null) {
                notice = new UpkeepPickupNotice();

                notice.setBizOrderNo(order.getBizNo());
                notice.setNoticeDate(new Date());
                notice.setWhCode(orderExcuteVo.getWhCode());
                notice.setAccessType(OrderEnums.AccessType.OUT.getCode());//出
                notice.setPickingType(NoticeStatusEnums.NoticeType.UPP_OUT.getCode());//64设备保养 备件出库
                notice.setNoticeStatus(NoticeStatusEnums.NoticeStatus.CONFIRM.getStatusCode());//直接确认
                noticeMap.put(orderExcuteVo.getWhCode(), notice);
                voMap.put(orderExcuteVo.getWhCode(), new ArrayList<OrderExcuteLineVo>());
            }
            voMap.get(orderExcuteVo.getWhCode()).add(orderExcuteVo);
        }
        // 生成通知单明细
        for(Map.Entry<String,UpkeepPickupNotice> entry : noticeMap.entrySet()) {
            UpkeepPickupNotice notice = entry.getValue();
            JpaUtil.save(notice);
            int lineNo = 0;
            for(OrderExcuteLineVo orderExcuteVo : voMap.get(entry.getKey())) {
                lineNo++;

                UpkeepPickupNoticeLine line = new UpkeepPickupNoticeLine();
                line.setOriginBizLineNo(orderExcuteVo.getBizOrderlineNo());
                line.setOriginBizNo(orderExcuteVo.getBizOrderNo());
                line.setItemCode(orderExcuteVo.getItemCode());
                line.setNoticeNo(notice.getNoticeNo());
                line.setQuantity(orderExcuteVo.getQuantity());

                line.setLineNo(lineNo+"");
                if (dbItemMap.containsKey(orderExcuteVo.getItemCode())){
                    Item item = dbItemMap.get(orderExcuteVo.getItemCode());
                    line.setItemName(item.getItemName());
                    line.setItemSpec(item.getItemSpec());
                    line.setUnitCode(item.getUnitCode());
                    line.setDrawingNo(item.getDrawingNo());
                }
                JpaUtil.save(line);
                //增加通知单对应的单号和行号
                orderExcuteVo.setNoticeNo(notice.getNoticeNo());
                orderExcuteVo.setNoticeLineNo(line.getLineNo());
            }
        }
        //生成 备件领料出库仓单
        for(Map.Entry<String,UpkeepPickupNotice> entry : noticeMap.entrySet()) {
            UpkeepPickupNotice notice = entry.getValue();
            int lineNo = 0;
            WarehouseOrder wo = null;
            for(OrderExcuteLineVo vo : voMap.get(entry.getKey())){
                lineNo++;
                if(wo == null){
                    wo = new WarehouseOrder();
                    wo.setAccessType(notice.getAccessType());
                    wo.setBpmnStatus(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode());
                    wo.setCloseStatus(OrderStatusEnums.CloseStatus.OPEN.getStatusCode());
                    wo.setOrderStatus(OrderStatusEnums.OrderStatus.PLAN.getStatusCode());
                    wo.setOrderDate(new Date());
                    wo.setOriginBizNo(vo.getBizOrderNo());
                    wo.setWhCode(vo.getWhCode());
                    wo.setWoType(notice.getPickingType());
                    wo.setOriginNoticeNo(vo.getNoticeNo());//关联noticeno字段
                    JpaUtil.save(wo);
                }
                WarehouseOrderLine line = new WarehouseOrderLine();
                line.setWhCode(wo.getWhCode());
                line.setCloseStatus(OrderStatusEnums.CloseStatus.OPEN.getStatusCode());
                Item item = dbItemMap.get(vo.getItemCode());
                line.setItemCode(vo.getItemCode());
                line.setItemGroupCode(item.getItemGroupCode());
                line.setItemName(item.getItemName());
                line.setItemSpec(item.getItemSpec());
                line.setUnitCode(item.getUnitCode());
                line.setDrawingNo(item.getDrawingNo());
                line.setQuantity(vo.getQuantity());
                line.setBizNo(wo.getBizNo());
                line.setLineNo(lineNo+"");
                line.setOriginBizNo(vo.getBizOrderNo());
                line.setOriginBizLineNo(vo.getBizOrderlineNo());
                line.setSort(vo.getSort());
                line.setOriginNoticeNo(vo.getNoticeNo());
                line.setOriginNoticeLineNo(vo.getNoticeLineNo());
                JpaUtil.save(line);
            }
        }
        return Result.OK(pickupLineList);
    }

    @Override
    @Transactional
    public Result<Object> executeReturn(EquipmentUpkeepTask order, List<OrderExcuteLineVo> lines) {
        if (lines==null||lines.isEmpty()){
            return Result.error("提交数据为空");
        }
        Set<String> itemCodeSet = lines.stream().map(OrderExcuteLineVo::getItemCode).collect(Collectors.toSet());
        List<Item> dbItemList = JpaUtil.linq(Item.class).in("itemCode", itemCodeSet).list();
        Map<String,Item> dbItemMap = JpaUtil.index(dbItemList, "itemCode");
        //生成对应通知单
        Map<String, UpkeepReturnBomNotice> noticeMap = new HashMap<>();
        Map<String,List<OrderExcuteLineVo>> voMap = new HashMap<>();
        for(OrderExcuteLineVo orderExcuteVo : lines) {
            UpkeepReturnBomNotice notice = noticeMap.get(orderExcuteVo.getWhCode());
            if(notice == null) {
                notice = new UpkeepReturnBomNotice();

                notice.setBizOrderNo(order.getBizNo());
                notice.setNoticeDate(new Date());
                notice.setWhCode(orderExcuteVo.getWhCode());
                notice.setAccessType(OrderEnums.AccessType.IN.getCode());//出
                notice.setPickingType(NoticeStatusEnums.NoticeType.UPP_IN.getCode());//65 保养备件退料入库
                notice.setNoticeStatus(NoticeStatusEnums.NoticeStatus.CONFIRM.getStatusCode());//直接确认
                noticeMap.put(orderExcuteVo.getWhCode(), notice);
                voMap.put(orderExcuteVo.getWhCode(), new ArrayList<OrderExcuteLineVo>());
            }
            voMap.get(orderExcuteVo.getWhCode()).add(orderExcuteVo);
        }
        // 生成通知单明细
        for(Map.Entry<String,UpkeepReturnBomNotice> entry : noticeMap.entrySet()) {
            UpkeepReturnBomNotice notice = entry.getValue();
            JpaUtil.save(notice);
            int lineNo = 0;
            for(OrderExcuteLineVo orderExcuteVo : voMap.get(entry.getKey())) {
                lineNo++;

                UpkeepReturnBomNoticeLine line = new UpkeepReturnBomNoticeLine();
                line.setOriginBizLineNo(orderExcuteVo.getBizOrderlineNo());
                line.setOriginBizNo(orderExcuteVo.getBizOrderNo());
                line.setItemCode(orderExcuteVo.getItemCode());
                line.setNoticeNo(notice.getNoticeNo());
                line.setQuantity(orderExcuteVo.getQuantity());

                line.setLineNo(lineNo+"");
                if (dbItemMap.containsKey(orderExcuteVo.getItemCode())){
                    Item item = dbItemMap.get(orderExcuteVo.getItemCode());
                    line.setItemName(item.getItemName());
                    line.setItemSpec(item.getItemSpec());
                    line.setUnitCode(item.getUnitCode());
                    line.setDrawingNo(item.getDrawingNo());
                }
                line.setLotNo(orderExcuteVo.getLotNo());
                line.setSubLotIndex(orderExcuteVo.getSubLotIndex());
                JpaUtil.save(line);
                //增加通知单对应的单号和行号
                orderExcuteVo.setNoticeNo(notice.getNoticeNo());
                orderExcuteVo.setNoticeLineNo(line.getLineNo());
            }
        }

        //生成 备件退料入库仓单
        for(Map.Entry<String,UpkeepReturnBomNotice> entry : noticeMap.entrySet()) {
            UpkeepReturnBomNotice notice = entry.getValue();
            int lineNo = 0;
            WarehouseOrder wo = null;
            for(OrderExcuteLineVo vo : voMap.get(entry.getKey())){
                lineNo++;
                if(wo == null){
                    wo = new WarehouseOrder();
                    wo.setAccessType(notice.getAccessType());
                    wo.setBpmnStatus(OrderStatusEnums.BpmnStatus.AUDITED.getStatusCode());
                    wo.setCloseStatus(OrderStatusEnums.CloseStatus.OPEN.getStatusCode());
                    wo.setOrderStatus(OrderStatusEnums.OrderStatus.PLAN.getStatusCode());
                    wo.setOrderDate(new Date());
                    wo.setOriginBizNo(vo.getBizOrderNo());
                    wo.setWhCode(vo.getWhCode());
                    wo.setWoType(notice.getPickingType());
                    wo.setOriginNoticeNo(vo.getNoticeNo());//关联noticeno字段
                    JpaUtil.save(wo);
                }
                WarehouseOrderLine line = new WarehouseOrderLine();
                line.setWhCode(wo.getWhCode());
                line.setCloseStatus(OrderStatusEnums.CloseStatus.OPEN.getStatusCode());
                Item item = dbItemMap.get(vo.getItemCode());
                line.setItemCode(vo.getItemCode());
                line.setItemGroupCode(item.getItemGroupCode());
                line.setItemName(item.getItemName());
                line.setItemSpec(item.getItemSpec());
                line.setUnitCode(item.getUnitCode());
                line.setDrawingNo(item.getDrawingNo());
                line.setQuantity(vo.getQuantity());
                line.setBizNo(wo.getBizNo());
                line.setLineNo(lineNo+"");
                line.setOriginBizNo(vo.getBizOrderNo());
                line.setOriginBizLineNo(vo.getBizOrderlineNo());
                line.setSort(vo.getSort());
                line.setOriginNoticeNo(vo.getNoticeNo());
                line.setOriginNoticeLineNo(vo.getNoticeLineNo());
                line.setLotNo(vo.getLotNo());
                line.setSubLotIndex(vo.getSubLotIndex());
                JpaUtil.save(line);
            }
        }
        return Result.OK();
    }

    @Override
    @Transactional
    public Result<String> deleteWithSub(List<String> bizNoList) {
        if (bizNoList==null||bizNoList.isEmpty()){
            return Result.error("查询参数为空");
        }
        Criteria criteria = Criteria.create();
        criteria.addCriterion("bizNo",Operator.IN,bizNoList);
        List<EquipmentUpkeepTask> dblist = this.list(EquipmentUpkeepTask.class, criteria);
        if (dblist.isEmpty()){
            return Result.error("查询参数匹配的保养任务数据为空");
        }
        for (EquipmentUpkeepTask task:dblist){
            if (!EquipmentEnums.UpkeepStatus.START.getCode().equals(task.getOrderStatus())){
                return Result.error(("存在非待下达状态的工单【"+task.getBizNo()+"】，仅待下达状态下可以执行删除操作！"));
            }
        }

        for (EquipmentUpkeepTask task:dblist){
            String bizNo = task.getBizNo();

            JpaUtil.lind(EquipmentUpkeepTaskDetail.class).equal("bizNo", bizNo).delete();
            JpaUtil.lind(EquipmentUpkeepTaskOperation.class).equal("bizNo", bizNo).delete();
            JpaUtil.lind(EquipmentUpkeepTaskTransfer.class).equal("bizNo", bizNo).delete();
            JpaUtil.lind(EquipmentUpkeepTaskEvaluate.class).equal("bizNo", bizNo).delete();
            JpaUtil.lind(EquipmentUpkeepTaskProgress.class).equal("bizNo", bizNo).delete();
            JpaUtil.lind(EquipmentUpkeepTaskAssistants.class).equal("bizNo", bizNo).delete();
            JpaUtil.lind(EquipmentUpkeepTaskDetailParam.class).equal("bizNo", bizNo).delete();
            JpaUtil.lind(EquipmentUpkeepTaskPickupLine.class).equal("bizNo", bizNo).delete();
            JpaUtil.lind(EquipmentUpkeepTask.class).equal("bizNo", bizNo).delete();
        }
        return Result.OK();
    }

    @Override
    @Transactional
    public Result<?> shut(EquipmentUpkeepTask task) {
        EquipmentUpkeepTask bean = this.getById(EquipmentUpkeepTask.class, task.getBizNo());
        if (bean == null ) {
            return Result.error("未找到实体对象");
        }
        if (Integer.parseInt(bean.getOrderStatus())>=Integer.parseInt(EquipmentEnums.UpkeepStatus.REPORT.getCode())){
            return Result.error("仅待汇报之前状态可以否决！");
        }
        bean.setOrderStatus(EquipmentEnums.UpkeepStatus.SHUT.getCode());
        bean.setVetoReason(task.getVetoReason());
        this.update(bean);

        insertOperate(bean.getBizNo(), "关闭（异常关闭）", task.getVetoReason());
        return Result.OK(bean);
    }

    @Override
    @Transactional(readOnly = false)
    public Result<EquipmentUpkeepTask> updateOccupy(EquipmentUpkeepTask task) throws Exception {
        if (true){//开启pmis占用校验
            try {
                String sql = "SELECT  e.EQUIPMENTNAME  FROM EQUIPMENT e where e.EQUIPMENTNAME ='"+task.getTargetId()+"'";
                DataGridWrapper dataGridWrapper = dbService.queryTableData(dbInfoId, "", sql, 1, 1);
                log.info(dataGridWrapper.toString());
                if (dataGridWrapper!=null&&dataGridWrapper.getTotalCount()==0){
                    log.warn("保养单对应的设备信息没有在PMIS系统存在，不发起占用接口调用，直接更新工单状态为已排产。 ");
                    task.setPmisHold(EquipmentEnums.PmisHode.PRODUCTIONSCHEDULED.getCode());//直接更新为已排产
                    this.update(task);
                    return Result.OK(task);
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error(e.getMessage());
            }
        }
        return Result.OK(task);
        //正常调用占用接口
        /*JSONObject obj = new JSONObject();
        obj.put("scheduledDownNo", task.getBizNo());
        obj.put("workUnitName", task.getTargetId());
        obj.put("plannedStartedDate",DateUtil.formatDateTime(task.getPlanStartTime()));
        obj.put("plannedEndedDate",DateUtil.formatDateTime(task.getPlanEndTime()));
        obj.put("reasonId",15);
        log.info("占用接口调用入参构造: " + obj.toJSONString());
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> entity = new HttpEntity<String>(obj.toJSONString(),headers);
        log.info("占用接口地址: " + create);
        log.info("占用接口传参: " + entity);
        ResponseEntity<String> resp = restTemplate.exchange(create, HttpMethod.POST, entity, String.class);
        Integer statusCode = resp.getStatusCodeValue();
        log.info("占用接口调用返回code: " + statusCode);
        if(200==statusCode){
            log.info("占用接口调用返回结果： " + resp.getBody());
            JSONObject respBody = JSONObject.parseObject(resp.getBody());
            if(respBody.containsKey("success")&&respBody.get("success").equals(Boolean.TRUE)){
                task.setPmisHold(EquipmentEnums.PmisHode.PUSHED.getCode());
                this.update(task);
                log.info("接口调用成功");
                return Result.OK(task);
            }else{
                log.error("接口调用失败："+ new String(respBody.get("errorMessage").toString().getBytes("ISO-8859-1"), "utf-8"));
                return Result.error("占用接口调用失败："+ new String(respBody.get("errorMessage").toString().getBytes("ISO-8859-1"), "utf-8"));
            }
        }else{
            log.error("接口调用失败，状态码："+statusCode+"，返回结果："+resp.getBody());
            return Result.error("接口调用失败，状态码："+statusCode);
        }*/
    }

    @Override
    @Transactional
    public Result<EquipmentUpkeepTask> updateTime(EquipmentUpkeepTask equipmentUpkeepTask, EquipmentEnums.PmisHode productionscheduled) {
        if (equipmentUpkeepTask == null || equipmentUpkeepTask.getBizNo() == null || equipmentUpkeepTask.getBizNo().isEmpty()){
            return Result.error("设备维护任务的bizNo不能为空");
        }
        EquipmentUpkeepTask byId = this.getById(EquipmentUpkeepTask.class, equipmentUpkeepTask.getBizNo());
        if (byId == null){
            return Result.error("没有找到该"+equipmentUpkeepTask.getBizNo()+"维护的任务");
        }
        // 日志记录开始时间
        log.info("开始更新设备维护任务时间，任务ID: {}", equipmentUpkeepTask.getBizNo());
        byId.setPlanStartTime(equipmentUpkeepTask.getPlanStartTime());// 开始时间
        byId.setPlanEndTime(equipmentUpkeepTask.getPlanEndTime());// 结束时间
        byId.setPmisHold(productionscheduled.getCode());// 占用状态
        try {
            this.update(byId);
            log.info("设备维护任务更新成功，任务ID: {}", equipmentUpkeepTask.getBizNo());
            return Result.OK();
        } catch (Exception e) {
            log.error("设备维护任务更新失败，任务ID: {}", equipmentUpkeepTask.getBizNo(), e);
            return Result.error("设备维护任务更新失败：" + e.getMessage());
        }
    }

    /**
     * 当前登录用户协助的工单信息
     * @param criteria
     * @param page
     * @return
     */
    @Override
    @Transactional
    public Page<EquipmentUpkeepTask> userAssistedTickets(Criteria criteria, Pageable page) {
        //获取当前登录用户大的信息
//        User sysUser = SecurityUtils.getLoginUser();
//        String username = sysUser.getUsername();
        List<EquipmentUpkeepTaskAssistants> list1 = equipmentUpkeepTaskAssistantsService.userAssistance();
        if (list1 != null){
            List<EquipmentUpkeepTask> list2 = this.list(EquipmentUpkeepTask.class, criteria);
            ArrayList<EquipmentUpkeepTask> equipmentUpkeepTasks = new ArrayList<>();
            for (EquipmentUpkeepTaskAssistants Assistants : list1) {
                for (EquipmentUpkeepTask upkeepTask : list2) {
                    if (Assistants.getBizNo().equals(upkeepTask.getBizNo())) {
                        equipmentUpkeepTasks.add(upkeepTask);
                    }
                }
            }
            PageImpl<EquipmentUpkeepTask> upkeepTasks = new PageImpl<>(equipmentUpkeepTasks, page, equipmentUpkeepTasks.size());
            return upkeepTasks;
        }
        return new PageImpl<>(Collections.emptyList(), page, 0);
    }

    @Override
    @Transactional
    public void adminUpdateTask(EquipmentUpkeepTask upkeepTask) {
        EquipmentUpkeepTask byId = this.getById(EquipmentUpkeepTask.class, upkeepTask.getBizNo());
        //重新计算计划下达时间
        if (upkeepTask.getIsAutoRelease() == Integer.parseInt(CommonEnums.YesNo.YES.getCode())) {//自动释放
            upkeepTask.setPlanReleaseTime(DateUtils.addDays(upkeepTask.getPlanStartTime(), 0 - upkeepTask.getAdvanceTime()));
            byId.setPlanReleaseTime(upkeepTask.getPlanReleaseTime());
        }
        /*if (EquipmentEnums.UpkeepPlanTarget.AREA_TARGET.getCode().equals(upkeepTask.getTargetType())) {
            // 查询区域信息
            EquipmentArea area = JpaUtil.getOne(EquipmentArea.class,upkeepTask.getTargetId());
            if (area == null) {
                return;
            }
            upkeepTask.setTargetCode(area.getAreaCode());
            if (area.getPid() != null && !"0".equals(area.getPid())) {
                String parentAllName = equipmentAreaService.getParentAllNameByPid(area.getPid());
                upkeepTask.setTargetName(parentAllName +"/"+ area.getAreaName());
            } else {
                upkeepTask.setTargetName(area.getAreaName());
            }
        }
        // 获取部门或群组的负责人
        if (DEPART_RELEASE_TARGET.equals(upkeepTask.getReleaseTargetType())) {
            String departmentDirector = getDepartmentDirector(upkeepTask.getReleaseTargetId(), upkeepTask.getDispatchMode());
            upkeepTask.setDirector(departmentDirector);
        } else if (PERSON_GROUP_RELEASE_TARGET.equals(upkeepTask.getReleaseTargetType())) {
            // 获取群组主管
            EquipmentPersonGroup tpmPersonGroup = JpaUtil.getOne(EquipmentPersonGroup.class,upkeepTask.getReleaseTargetId());
            if (StringUtils.isEmpty(tpmPersonGroup.getDirectorId()) && ASSIGN_MODE.equals(upkeepTask.getDispatchMode())) {
                throw new MBootException("派工模式下该下达目标无负责人");
            }
            upkeepTask.setDirector(tpmPersonGroup.getDirectorId());
        }*/
//        byId.setTargetId(upkeepTask.getTargetId());
//        byId.setUpkeepPersonGroupCode(upkeepTask.getUpkeepPersonGroupCode());
//        byId.setEngineerPersonGroupCode(upkeepTask.getEngineerPersonGroupCode());
//        byId.setUpkeepType(upkeepTask.getUpkeepType());
//        byId.setPlanStartTime(upkeepTask.getPlanStartTime());
//        byId.setPlanHourRation(upkeepTask.getPlanHourRation());
//        byId.setPlanEndTime(upkeepTask.getPlanEndTime());
//        byId.setIsAutoRelease(upkeepTask.getIsAutoRelease());
        this.update(upkeepTask);

    }
}
